package me.xADudex.RandomLocation;

import org.bukkit.event.entity.*;
import org.bukkit.entity.*;
import org.bukkit.event.*;
import org.bukkit.command.*;
import org.bukkit.event.block.*;
import org.bukkit.block.*;
import org.bukkit.event.player.*;
import org.bukkit.*;
import org.bukkit.plugin.*;
import java.util.*;
import org.bukkit.event.inventory.*;
import org.bukkit.inventory.*;
import org.bukkit.event.world.*;

public class Events implements Listener
{
    private Main pl;
    HashMap<String, String> kitEdit;
    HashMap<String, Location> respawnLocation;
    ArrayList<UUID> bypassWorldListenerPlayers;
    
    Events(final Main main) {
        this.kitEdit = new HashMap<String, String>();
        this.respawnLocation = new HashMap<String, Location>();
        this.bypassWorldListenerPlayers = new ArrayList<UUID>();
        (this.pl = main).getDataFolder();
    }
    
    @EventHandler(priority = EventPriority.HIGHEST)
    public void onDamage(final EntityDamageEvent event) {
        if (event.getEntity() instanceof Player) {
            final Player p = (Player)event.getEntity();
            if (this.pl.timer.godsContains(p)) {
                event.setCancelled(true);
            }
        }
    }
    
    @EventHandler
    public void onSignChange(final SignChangeEvent event) {
        if (event.getLine(0).equalsIgnoreCase("[rl]") && event.getPlayer().hasPermission("RandomLocation.Admin")) {
            if (event.getLine(1).equalsIgnoreCase("")) {
                event.getPlayer().sendMessage(ChatColor.GREEN + "You need to specify a zone name on the second line");
            }
            else {
                event.setLine(0, ChatColor.GREEN + "[RL]");
                ChatColor c = ChatColor.AQUA;
                if (event.getLine(1).startsWith("&")) {
                    c = ChatColor.getByChar(event.getLine(1).charAt(1));
                    event.setLine(1, event.getLine(1).substring(2));
                    if (c == null) {
                        c = ChatColor.AQUA;
                    }
                }
                event.setLine(1, c + this.pl.zoneManager.getZoneName(event.getLine(1)));
            }
        }
    }
    
    @EventHandler
    public void onInteract(final PlayerInteractEvent event) {
        if (event.getClickedBlock() != null) {
            final Player p = event.getPlayer();
            if (event.getClickedBlock().getState() instanceof Sign) {
                final Sign s = (Sign)event.getClickedBlock().getState();
                final String rip = s.getLine(0).replaceAll("��.", "");
                if (rip.equalsIgnoreCase("[rl]") && !rip.equals(s.getLine(0)) && !s.getLine(1).equalsIgnoreCase("")) {
                    if (p.hasPermission("RandomLocation.Use") || p.hasPermission("RandomLocation.Admin") || this.pl.getConfig().getBoolean("Permissions.OpenSigns") || p.hasPermission("RandomLocation.UseSign")) {
                        if (!event.getAction().equals((Object)Action.RIGHT_CLICK_BLOCK)) {
                            if (!p.hasPermission("RandomLocation.Admin")) {
                                event.setCancelled(true);
                            }
                            return;
                        }
                        this.pl.zoneManager.teleportPlayer(event.getPlayer(), (CommandSender)event.getPlayer(), s.getLine(1).replaceAll("��.", ""), TeleportSource.SIGN);
                    }
                    else {
                        p.sendMessage(ChatColor.DARK_RED + "You don't got permission to use that sign!");
                    }
                    event.setCancelled(true);
                }
            }
        }
    }
    
    @EventHandler
    public void onJoin(final PlayerJoinEvent event) {
        if (this.pl.getConfig().getBoolean("TeleportOnFirstJoin.Enable") && !event.getPlayer().hasPlayedBefore()) {
            this.pl.zoneManager.teleportPlayer(event.getPlayer(), (CommandSender)event.getPlayer(), this.pl.getConfig().getString("TeleportOnFirstJoin.Zone"), TeleportSource.OVERRIDE);
        }
        if (this.pl.getConfig().getBoolean("AutoUpdater.PromptAdminForUpdate") && this.pl.updateMsg != null && event.getPlayer().hasPermission("RandomLocation.Admin")) {
            event.getPlayer().sendMessage(this.pl.updateMsg);
        }
    }
    
    @EventHandler
    public void onCommandPreProcess(final PlayerCommandPreprocessEvent event) {
        final String first = event.getMessage().replaceFirst("/", "").split(" ")[0];
        if (this.pl.getConfig().contains("Aliases") && this.pl.getConfig().getConfigurationSection("Aliases") != null && this.pl.getConfig().getConfigurationSection("Aliases").getKeys(false) != null) {
            for (final String key : this.pl.getConfig().getConfigurationSection("Aliases").getKeys(false)) {
                if (key.equalsIgnoreCase(first)) {
                    this.pl.zoneManager.teleportPlayer(event.getPlayer(), (CommandSender)event.getPlayer(), this.pl.getConfig().getString("Aliases." + key), TeleportSource.COMMAND);
                    event.setCancelled(true);
                }
            }
        }
    }
    
    BlockFace getDirection(final Sign s) {
        String meta = s.getData().toString();
        if (meta.contains("SIGN_POST")) {
            return BlockFace.DOWN;
        }
        meta = meta.split(" facing ")[1];
        return BlockFace.valueOf(meta).getOppositeFace();
    }
    
    @EventHandler
    public void onBlockBreak(final BlockBreakEvent event) {
        if (!event.getPlayer().hasPermission("RandomLocation.Admin")) {
            final Block[] blocks = { event.getBlock(), event.getBlock().getRelative(BlockFace.UP), event.getBlock().getRelative(BlockFace.NORTH), event.getBlock().getRelative(BlockFace.SOUTH), event.getBlock().getRelative(BlockFace.EAST), event.getBlock().getRelative(BlockFace.WEST) };
            Block[] array;
            for (int length = (array = blocks).length, i = 0; i < length; ++i) {
                final Block b = array[i];
                if (b != null && b.getState() instanceof Sign) {
                    final Sign s = (Sign)b.getState();
                    final String rip = s.getLine(0).replaceAll("��.", "");
                    if (rip.equalsIgnoreCase("[rl]") && !rip.equals(s.getLine(0)) && !s.getLine(1).equalsIgnoreCase("") && b.getRelative(this.getDirection(s)).equals(event.getBlock())) {
                        event.setCancelled(true);
                    }
                }
            }
        }
    }
    
    @EventHandler
    public void onPortalTeleport(final PlayerPortalEvent event) {
        for (final Zone z : this.pl.zoneManager.getPortals()) {
            if (z.getWorld() != null && z.getWorld().getName().equals(event.getFrom().getWorld().getName()) && z.portalCheck(event.getPlayer())) {
                event.setCancelled(true);
                break;
            }
        }
        if (!event.isCancelled()) {
            this.onTeleport((PlayerTeleportEvent)event);
        }
    }
    
    @EventHandler(priority = EventPriority.LOWEST)
    public void onRespawnFirst(final PlayerRespawnEvent event) {
        if (!this.pl.getConfig().getBoolean("IgnoreOtherPlugins") && event.getRespawnLocation() != null) {
            this.respawnLocation.put(event.getPlayer().getName(), event.getRespawnLocation());
        }
    }
    
    @EventHandler(priority = EventPriority.HIGHEST)
    public void onRespawn(final PlayerRespawnEvent event) {
        if (this.pl.getConfig().isConfigurationSection("Respawn")) {
            if (!this.pl.getConfig().getBoolean("IgnoreBed") && event.isBedSpawn()) {
                return;
            }
            if (!this.pl.getConfig().getBoolean("IgnoreOtherPlugins") && (event.getRespawnLocation() != null || this.respawnLocation.containsKey(event.getPlayer().getName())) && !event.getRespawnLocation().equals((Object)this.respawnLocation.get(event.getPlayer().getName()))) {
                return;
            }
            this.respawnLocation.remove(event.getPlayer().getName());
            final Set<String> perms = (Set<String>)this.pl.getConfig().getConfigurationSection("Respawn").getKeys(false);
            if (perms != null) {
                for (final String perm : perms) {
                    if (event.getPlayer().hasPermission("RandomLocation." + perm)) {
                        Bukkit.getScheduler().scheduleSyncDelayedTask((Plugin)this.pl, (Runnable)new Runnable() {
                            @Override
                            public void run() {
                                final String dest = Events.this.pl.getConfig().getString("Respawn." + perm);
                                if (dest.equalsIgnoreCase("<LastLocation>")) {
                                    final Location loc = Events.this.pl.zoneManager.playersTeleportToZoneLog.get(event.getPlayer().getUniqueId());
                                    if (loc == null) {
                                        if (Events.this.pl.getConfig().getBoolean("MessageOnTeleport")) {
                                            event.getPlayer().sendMessage(ChatColor.GREEN + "Could not teleport you to your last random location");
                                            event.getPlayer().sendMessage(ChatColor.GREEN + "Your last random location was not found");
                                        }
                                    }
                                    else {
                                        event.getPlayer().teleport(loc);
                                        if (Events.this.pl.getConfig().getBoolean("MessageOnTeleport")) {
                                            event.getPlayer().sendMessage(ChatColor.GREEN + "Teleported you to your last random location");
                                        }
                                    }
                                }
                                else {
                                    Events.this.pl.zoneManager.teleportPlayer(event.getPlayer(), (CommandSender)event.getPlayer(), dest, TeleportSource.OVERRIDE);
                                }
                            }
                        }, 1L);
                        break;
                    }
                }
            }
        }
    }
    
    @EventHandler(ignoreCancelled = true)
    public void onTeleport(final PlayerTeleportEvent event) {
        if (!this.bypassWorldListenerPlayers.contains(event.getPlayer().getUniqueId()) && event.getTo() != null && (event.getFrom() == null || !event.getFrom().getWorld().getName().equals(event.getTo().getWorld().getName())) && this.pl.getConfig().isConfigurationSection("WorldTravelListener")) {
            for (final String world : this.pl.getConfig().getConfigurationSection("WorldTravelListener").getKeys(false)) {
                if (world.equalsIgnoreCase(event.getTo().getWorld().getName())) {
                    if (event.getFrom() != null) {
                        event.setCancelled(true);
                    }
                    this.bypassWorldListenerPlayers.add(event.getPlayer().getUniqueId());
                    this.pl.zoneManager.teleportPlayer(event.getPlayer(), (CommandSender)event.getPlayer(), this.pl.getConfig().getString("WorldTravelListener." + world), TeleportSource.OVERRIDE);
                    this.bypassWorldListenerPlayers.remove(event.getPlayer().getUniqueId());
                    break;
                }
            }
        }
    }
    
    @EventHandler
    public void onInvClose(final InventoryCloseEvent event) {
        if (event.getPlayer() instanceof Player) {
            final Player p = (Player)event.getPlayer();
            if (this.kitEdit.containsKey(p.getName())) {
                final HashMap<Integer, ItemStack> items = new HashMap<Integer, ItemStack>();
                for (int i = 0; i < event.getInventory().getSize(); ++i) {
                    final ItemStack item = event.getInventory().getItem(i);
                    if (item != null) {
                        items.put(i, item);
                    }
                }
                final String zn = this.kitEdit.get(p.getName());
                if (this.pl.zoneManager.setItems(zn, items) != null) {
                    p.sendMessage(ChatColor.GREEN + "Successfully saved the starter kit for zone " + zn);
                }
                else {
                    p.sendMessage(ChatColor.GREEN + "Seems that the zone you where editing the kit for has been deleted");
                }
                this.kitEdit.remove(p.getName());
            }
        }
    }
    
    @EventHandler
    public void onChunkUnload(final ChunkUnloadEvent event) {
        if (this.pl.zoneManager.isLoadedZone(event.getChunk())) {
            event.setCancelled(true);
        }
    }
}
